<template>
    <div style="height: 100%;">
        <!--  表和列的展示  -->
        <div style="display: flex;height: 100%;">
            <div style="width: calc(40% - 40px);height: 100%;z-index: 1;">
                <!--   源表     -->
                <el-card shadow="never" style="margin: 5px;height: calc(100% - 12px);" class="table-in">
                    <template #header>
                        <div class="e-page font-auto-resize" style="white-space: nowrap;">
                            <div style="display: flex;">
                                <div :style="`width: calc(100% - var(--font-size) * 15 - ${dbTypes?.length ? '50px' : '0px'});`"
                                    class="flex-display-center">
                                    <tooltip v-model="etlInfo.in.table" placeholder="请选择源表信息"
                                        v-if="!etlInfo.in.customize" dblcopy border />
                                    <tooltip :placeholder="placeholderIn" v-else border />
                                </div>
                                <div style="width: 50px;" class="flex-display-center" v-if="dbTypes?.length">
                                    <el-button class="button-auto-resize" :icon="getIcon('search')" type="primary"
                                        circle @click="showDrawer = true; direction = 'ltr'" />
                                </div>
                                <div class="flex-display-center" style="width: calc(var(--font-size) * 7);">
                                    <div style="width: 110px;text-align: right;padding-right: 10px;">自定义SQL:</div>
                                    <el-checkbox v-model="etlInfo.in.customize" @change="customizeChange"
                                        :disabled="!etlInfo.in.table" />
                                </div>
                                <div class="flex-display-center" style="width: calc(var(--font-size) * 8);">
                                    <div style="width: 110px;text-align: right;padding-right: 10px;">只显示选中:</div>
                                    <el-checkbox v-model="etlInfo.in.onlyChecked" :disabled="checkboxInDisable"
                                        @change="checkboxInChange" />
                                </div>
                            </div>
                        </div>
                    </template>
                    <el-form :model="etlInfo.in" :rules="inTableRule" ref="sqlColumnRef" spellcheck="false"
                        :validate-on-rule-change="false" @submit.native.prevent v-show="etlInfo.in.customize">
                        <el-form-item prop="customizeSql" class="sqlColumn">
                            <aceEditor v-model="etlInfo.in.customizeSql" :options="{ lang: 'sql' }" />
                        </el-form-item>
                    </el-form>
                    <el-table :data="showInData" border v-loading="searchTabLoading" height="100%"
                        header-cell-class-name="el-table-header-cell" cell-class-name="el-table-cell"
                        class="e-page inTable" @selection-change="inSelect" ref="tableInRef" @row-click="rowInClick"
                        row-key="rn" v-show="!etlInfo.in.customize" highlight-current-row>
                        <el-table-column type="selection" width="40" :selectable="inSelectable" />
                        <el-table-column prop="rn" label="序号" width="80" />
                        <el-table-column prop="name" label="字段名称" min-width="180" />
                        <el-table-column prop="column_type" label="字段类型" min-width="150" />
                    </el-table>
                </el-card>
            </div>
            <div class="relationContainer">
                <el-icon link class="icon">
                    <component :is="getIcon('DArrowRight')" />
                </el-icon>
            </div>
            <div style="width: calc(40% - 40px);height: 100%;z-index: 1;">
                <!--   目标表     -->
                <el-card shadow="never" style="margin: 5px;height: calc(100% - 12px);" class="table-out">
                    <template #header>
                        <div class="e-page font-auto-resize" style="white-space: nowrap">
                            <div style="display: flex;">
                                <div :style="`width: calc(100% - var(--font-size) * 7 - ${dbTypes?.length ? '50px' : '0px'});`"
                                    class="flex-display-center">
                                    <tooltip v-model="etlInfo.out.table" placeholder="请选择目标表信息" dblcopy border />
                                </div>
                                <div style="width: 50px;" class="flex-display-center" v-if="dbTypes?.length">
                                    <el-button class="button-auto-resize" :icon="getIcon('search')" type="primary"
                                        circle @click="showDrawer = true; direction = 'rtl'" />
                                </div>
                                <div style="width: calc(var(--font-size) * 7);" class="flex-display-center">
                                    <div style="width: 110px;text-align: right;padding-right: 10px;">只显示选中:</div>
                                    <el-checkbox v-model="etlInfo.out.onlyChecked" :disabled="checkboxOutDisable"
                                        @change="checkboxOutChange" />
                                </div>
                            </div>
                        </div>
                    </template>
                    <el-table :data="showOutData" border v-loading="searchTabLoading" height="100%"
                        header-cell-class-name="el-table-header-cell" cell-class-name="el-table-cell"
                        class="e-page outTable" @selection-change="outSelect" ref="tableOutRef" highlight-current-row
                        @row-click="rowOutClick" row-key="rn">
                        <el-table-column type="selection" width="40" :selectable="outSelectable" />
                        <el-table-column prop="rn" label="序号" width="80" />
                        <el-table-column prop="name" label="字段名称" min-width="180" />
                        <el-table-column prop="column_type" label="字段类型" min-width="150" />
                    </el-table>
                </el-card>
            </div>
            <div style="width: 20%;height: 100%;">
                <el-card shadow="never" style="margin: 5px;height: calc(100% - 12px);" class="table-where">
                    <el-row>
                        <el-divider content-position="left">并发</el-divider>
                        <div style="width: 100%;">
                            <el-input class="input-auto-resize" v-model="etlInfo.channel" />
                        </div>
                    </el-row>
                    <el-row>
                        <el-divider content-position="left">where</el-divider>
                        <div style="width: 100%;">
                            <el-input class="input-auto-resize" v-model="etlInfo.where" v-if="!etlInfo.in.customize" />
                            <tooltip placeholder="自定义SQL无需配置where项" v-else border />
                        </div>
                    </el-row>
                    <el-row>
                        <el-divider content-position="left">数据流向</el-divider>
                        <div style="display: flex;width: 100%;" class="font-auto-resize">
                            <div style="width: 100px;">
                                <span>From</span>
                            </div>
                            <div style="width: calc(100% - 100px);">
                                <span style="color: #00c0ff">{{ placeholderIn }}</span>
                            </div>
                        </div>
                        <div style="display: flex;padding-top: 10px;width: 100%;" class="font-auto-resize">
                            <div style="width: 100px;">
                                <span>To</span>
                            </div>
                            <div style="width: calc(100% - 100px);">
                                <span style="color: #289de9">{{ placeholderOut }}</span>
                            </div>
                        </div>
                    </el-row>
                </el-card>
            </div>
        </div>

        <!--  抽屉,tableIn,tableOut共用,选择表以及对应的列信息  -->
        <el-drawer v-model="showDrawer" :direction="direction" @open="open" :show-close="false" :with-header="false"
            :close-on-press-escape="false" @close="close" size="50%" append-to-body class="table-mapping-page">
            <el-form inline :model="tableForm" class="e-page form-item forbid-select" spellcheck="false"
                @submit.native.prevent>
                <div style="display: flex;">
                    <div style="padding-right: 5px;width: calc((100% - var(--font-size) * 2 + 10px)/3);">
                        <el-select v-model="tableForm.dbType" placeholder="请选择数据库" @change="clearDB" clearable
                            class="input-auto-resize">
                            <el-option v-for="item in dbTypes" :key="item" :label="item" :value="item">
                            </el-option>
                        </el-select>
                    </div>
                    <div style="padding-right: 5px;width: calc((100% - var(--font-size) * 2 + 10px)/3);">
                        <el-select v-model="tableForm.dbSequence" placeholder="请选择实例" class="input-auto-resize"
                            clearable @change="clearData">
                            <el-option v-for="(item, index) in dbNames" :key="index" :label="item.name"
                                :value="item.sequence">
                            </el-option>
                        </el-select>
                    </div>
                    <div style="padding-right: 5px;width: calc((100% - var(--font-size) * 2 + 10px)/3);">
                        <el-input v-model="tableForm.table" placeholder="表名称" clearable class="input-auto-resize" />
                    </div>
                    <div style="display: flex;justify-content: space-around;width: calc(var(--font-size) * 2 + 10px);">
                        <el-button type="primary" @click="searchTable" :loading="searchLoading"
                            class="button-auto-resize" :icon="getIcon('search')" circle :disabled="!tableForm.table" />
                    </div>
                </div>
            </el-form>
            <div style="height: 10px;" />
            <el-table :data="searchTableData" border v-loading="searchTabLoading" height="calc(100vh - 55px)"
                header-cell-class-name="el-table-header-cell" cell-class-name="el-table-cell" highlight-current-row>
                <el-table-column prop="table_name" label="表名" min-width="150" />
                <el-table-column prop="table_schema" label="所属用户" min-width="100" />
                <el-table-column prop="table_type" label="表类型" min-width="100" />
                <el-table-column fixed="right" label="操作" :width="operationWidth" className="operation-column">
                    <template #default="scope">
                        <el-button @click="getTableInfo(scope.row)" type="primary" class="button-auto-resize"
                            :icon="getIcon('Location')" circle :loading="locateTabLoading" />
                    </template>
                </el-table-column>
            </el-table>
        </el-drawer>
    </div>
</template>
<script setup>
import { useElMessage, useSetTableOperationWidth, useModalSize, useRequest } from "@usehook"
import { isInArray, deepCopy, getIcon } from "@/utils/tools"

const operationWidth = useSetTableOperationWidth(1)

let etlInfo = $ref({
    in: {
        table: "",
        onlyChecked: false,
        dbType: "",
        dbSequence: "",
        customize: false,
        customizeSql: "",
        column: "",
        tableColumn: ""
    },
    out: {
        table: "",
        onlyChecked: false,
        dbType: "",
        dbSequence: "",
        column: "",
        tableColumn: ""
    },
    channel: "",
    where: ""
})
//控制表查询抽屉
let showDrawer = $ref(false)
//控制抽屉展开方向                  
let direction = $ref('rtl')
let dbTypes = $ref([])
let dbNames = $ref([])
let db = $ref({})
//抽屉里查询导入导出表的form
let tableForm = $ref({ dbType: "", table: "", dbSequence: "" })
//抽屉里查询结果,选择导入导出表
let searchTableData = $ref([])
//抽屉中查询按钮的loading状态
let searchLoading = $ref(false)
//抽屉中查询结果tale的loading状态
let searchTabLoading = $ref(false)
//抽屉中选择完表后查询字段信息时按钮的loading状态
let locateTabLoading = $ref(false)
//导入的字段
let tableInData = $ref([])
//导出的字段
let tableOutData = $ref([])
let rules = $ref({
    table: { required: true, message: '右侧按钮选择表->', trigger: [] },
})
//选中的导入字段
let selectionInData = $ref([])
//选中的导出字段
let selectionOutData = $ref([])
//导入的只显示选中是否禁用
let checkboxInDisable = $ref(true)
//导出的只显示选中是否禁用
let checkboxOutDisable = $ref(true)

watchEffect(() => {
    //监听dbType,更新可选的dbname
    dbNames = db[tableForm.dbType]
    //监听选中的行信息,判断只显示选中按钮是否可用
    if (tableInData && selectionInData && tableInData.length === selectionInData.length) {
        checkboxInDisable = true
    } else checkboxInDisable = !(selectionInData && selectionInData.length > 0)

    if (tableOutData && selectionOutData && tableOutData.length === selectionOutData.length) {
        checkboxOutDisable = true
    } else checkboxOutDisable = !(selectionOutData && selectionOutData.length > 0)

    if (etlInfo.in.onlyChecked) {
        nextTick(() => {
            tableInRef.toggleAllSelection();
        })
    }

    if (etlInfo.out.onlyChecked) {
        nextTick(() => {
            tableOutRef.toggleAllSelection();
        })
    }

    if (etlInfo.in.customizeSql && etlInfo.in.customize) {
        sqlColumnRef.clearValidate('customizeSql')
    }
})

const placeholderIn = $computed(() => {
    return etlInfo.in.dbType && etlInfo.in.dbSequence ? etlInfo.in.dbType + '@' + getDbName(etlInfo.in.dbSequence) : "请选择源表信息";
})
const placeholderOut = $computed(() => {
    return etlInfo.out.dbType && etlInfo.out.dbSequence ? etlInfo.out.dbType + '@' + getDbName(etlInfo.out.dbSequence) : "请选择目标表信息";
})
const inTableRule = $computed(() => {
    let rule;
    if (etlInfo.in.customize) {
        rule = {
            table: { required: true, message: '右侧按钮选择表->', trigger: [] },
            customizeSql: [{ required: true, message: '自定义SQL不能为空', trigger: [] }]
        }
    } else {
        rule = rules;
    }
    return rule;
})
//计算导入的表数据
const showInData = $computed(() => {
    //只显示选中选中时只展示选中的数据
    if (etlInfo.in.onlyChecked) {
        return selectionInData;
    } else {
        return tableInData;
    }
})
//计算导出的表数据
const showOutData = $computed(() => {
    if (etlInfo.out.onlyChecked) {
        return selectionOutData;
    } else {
        return tableOutData;
    }
})

const getDbName = (dbSequence) => {
    let _db = deepCopy(db)
    let dbName = "";
    if (Object.keys(_db).length > 0) {
        Object.keys(_db).forEach((dbType) => {
            _db[dbType].forEach(e => {
                if (e.sequence === dbSequence) {
                    dbName = e.name;
                }
            })
        })
    }
    return dbName
}

const tableInRef = $ref(null)
//监听导入的只显示选中按钮状态
const checkboxInChange = (checked) => {
    //按钮取消选择时,恢复之前字段的选中状态
    if (!checked) {
        const _selectionInData = selectionInData
        nextTick(() => {
            tableInData.forEach((row) => {
                if (_selectionInData.includes(row)) {
                    tableInRef.toggleRowSelection(row);
                }
            })
            changeInHeadCheckboxDisplay("")
        })
    } else if (checked) {
        //按钮选中时,隐藏表头的全选按钮
        changeInHeadCheckboxDisplay("none")
    }
}
const sqlColumnRef = $ref(null)
const customizeChange = (checked) => {
    if (checked) {
        checkboxInDisable = true;
    } else {
        checkboxInDisable = selectionInData.length === tableInData.length || selectionInData.length === 0;
    }
    sqlColumnRef.clearValidate('customizeSql')
}
const tableOutRef = $ref(null)
const checkboxOutChange = (checked) => {
    if (!checked) {
        const _selectionOutData = selectionOutData
        nextTick(() => {
            tableOutData.forEach((row) => {
                if (_selectionOutData.includes(row)) {
                    tableOutRef.toggleRowSelection(row);
                }
            })
            changeOutHeadCheckboxDisplay("")
        })
    } else if (checked) {
        changeOutHeadCheckboxDisplay("none")
    }
}

//判断行是否可选
const inSelectable = () => {
    return !etlInfo.in.onlyChecked;
}

const outSelectable = () => {
    return !etlInfo.out.onlyChecked;
}

//监听表选中的数据
const inSelect = (selection) => {
    if (!etlInfo.in.onlyChecked) {
        selectionInData = selection;
    }
}

const outSelect = (selection) => {
    if (!etlInfo.out.onlyChecked) {
        selectionOutData = selection;
    }
}

//修改表头全选按钮隐藏和显示状态
const changeInHeadCheckboxDisplay = (display) => {
    const opacity = display === 'none' ? 0 : 1
    const inCheckBoxAll = document.querySelector(".inTable .el-table__header-wrapper .el-table__header .el-table-column--selection .el-checkbox")
    if (inCheckBoxAll) inCheckBoxAll.style.opacity = opacity;

}

const changeOutHeadCheckboxDisplay = (display) => {
    const opacity = display === 'none' ? 0 : 1
    const outCheckBoxAll = document.querySelector(".outTable .el-table__header-wrapper .el-table__header .el-table-column--selection .el-checkbox")
    if (outCheckBoxAll) outCheckBoxAll.style.opacity = opacity;
}

//打开抽屉,获取db信息
const open = () => {
    useModalSize()
}

const fillDbInfo = (_db, _dbTypes) => {
    db = _db
    dbTypes = _dbTypes
}
//关闭抽屉
const close = () => {
    useModalSize(false)
}
//dbType变化时清空已选择的dbname
const clearDB = () => {
    tableForm.dbSequence = ''
    clearData()
}

const clearData = () => {
    searchTableData = []
}

// 行点击事件，修改选中状态
const rowInClick = (row) => {
    tableInRef.toggleRowSelection(row)
}

// 行点击事件，修改选中状态
const rowOutClick = (row) => {
    tableOutRef.toggleRowSelection(row)
}

const emits = defineEmits(["change"])
//获取表信息,根据选中的表名及db信息,获取对应的表字段信息,区分导入导出
const getTableInfo = (row) => {
    let inDbSequence;
    let inDbType;
    let outDbSequence;
    let outDbType;

    if (!row.connection && !tableForm.dbSequence) {
        useElMessage.error("未找到表的所属连接信息,重新导入表或者手动选择连接信息")
        return;
    }

    if (direction === 'rtl') {
        outDbSequence = tableForm.dbSequence || row.connection.sequence;
        outDbType = tableForm.dbType || row.connection.dbType;
        emits("change", outDbSequence)
    } else if (direction === 'ltr') {
        inDbSequence = tableForm.dbSequence || row.connection.sequence;
        inDbType = tableForm.dbType || row.connection.dbType;
    } else {
        return;
    }

    locateTabLoading = true;

    const table = row.table_schema + "." + row.table_name

    if (direction === 'rtl') {
        etlInfo.out.table = table;
        etlInfo.out.dbSequence = outDbSequence;
        etlInfo.out.dbType = outDbType;
    } else if (direction === 'ltr') {
        etlInfo.in.table = table;
        etlInfo.in.dbSequence = inDbSequence;
        etlInfo.in.dbType = inDbType;
    }

    if (etlInfo.out.table === etlInfo.in.table && etlInfo.out.dbSequence === etlInfo.in.dbSequence) {
        useElMessage.error("输入输出的表不能一样")
        locateTabLoading = false
        return
    }

    useRequest({ url: "/data/table/getTableColumn", dbSequence: tableForm.dbSequence, table: row.table_name, tableSchema: row.table_schema }).then((resData) => {
        if (resData && resData.status) {
            if (direction === 'rtl') {
                tableOutData = resData.data;
                changeOutHeadCheckboxDisplay("");
                //重新选择表需要清空已选的字段信息,并取消只显示选中按钮
                selectionOutData = [];
                etlInfo.out.onlyChecked = false
            } else if (direction === 'ltr') {
                tableInData = resData.data;
                changeInHeadCheckboxDisplay("")
                //重新选择表需要清空已选的字段信息,并取消只显示选中按钮
                selectionInData = [];
                etlInfo.in.onlyChecked = false
            }
            showDrawer = false;
        } else {
            useElMessage.error("获取字段失败");
        }
    }).finally(() => {
        locateTabLoading = false
    })
}

//模糊查询表名后续查询字段信息
const searchTable = () => {
    searchLoading = true
    searchTabLoading = true
    useRequest({ url: "/data/table/search", ...tableForm }).then(resData => {
        if (resData && resData.status) {
            searchTableData = resData.data
        } else {
            useElMessage.error("查询失败");
        }
    }).finally(() => {
        searchLoading = false;
        searchTabLoading = false;
    })
}

//初始化加载数据
const fill = (data) => {
    //填充etlInfo必要展示信息
    etlInfo.in.table = data.in.table;
    etlInfo.in.dbType = data.in.dbType;
    etlInfo.in.dbSequence = data.in.dbSequence;
    etlInfo.out.table = data.out.table;
    etlInfo.out.dbType = data.out.dbType;
    etlInfo.out.dbSequence = data.out.dbSequence;
    etlInfo.channel = data.channel || "";
    etlInfo.where = data.where || "";
    etlInfo.in.customize = data.in.customize;
    etlInfo.in.customizeSql = data.in.customizeSql;

    //填充表字段数据
    tableInData = JSON.parse(data.in.tableColumn)
    tableOutData = JSON.parse(data.out.tableColumn)

    //根据选择的字段填充选中状态
    const inSelectionColumn = data.in.column ? data.in.column.split(';') : [];
    const outSelectionColumn = data.out.column ? data.out.column.split(';') : [];

    //填充导入的选中状态
    if (inSelectionColumn.length !== tableInData.length) {
        let index = 1;
        tableInData.forEach((row) => {
            if (isInArray(row.name, inSelectionColumn)) {
                nextTick(() => {
                    tableInRef.toggleRowSelection(row);
                    if (index === inSelectionColumn.length) {
                        etlInfo.in.onlyChecked = data.in.onlyChecked;
                    }
                    index++;
                })
            }
        })
    }
    //填充导出的选中状态
    if (outSelectionColumn.length !== tableOutData.length) {
        let index = 1;
        tableOutData.forEach((row) => {
            if (isInArray(row.name, outSelectionColumn)) {
                nextTick(() => {
                    tableOutRef.toggleRowSelection(row);
                    if (index === outSelectionColumn.length) {
                        etlInfo.out.onlyChecked = data.out.onlyChecked;
                    }
                    index++;
                })
            }
        })
    }

    if (!data.out.onlyChecked) {
        changeOutHeadCheckboxDisplay("")
    }

    if (!data.in.onlyChecked) {
        changeInHeadCheckboxDisplay("")
    }
}
//验证当前页面表格
const validate = async () => {
    // 1 正常 0 表单验证不通过 2 导入导出长度不对等
    let pass = 1

    if (!etlInfo.in.table) {
        useElMessage.error("请选择源表信息")
        pass = 0
    } else if (!etlInfo.out.table) {
        useElMessage.error("请选择目标表信息")
        pass = 0
    } else if (etlInfo.in.customize && !etlInfo.in.customizeSql) {
        useElMessage.error("请输入自定义sql")
        pass = 0
    } else if (getOutData().length !== getInData().length && !etlInfo.in.customize) {
        useElMessage.error("源表和目标表字段数量不对称")
        pass = 0
    }

    return pass
}

const tableInPadding = $computed(() => {
    return etlInfo.in.customize ? "0" : "10px"
})

const tableInHeight = $computed(() => {
    return etlInfo.in.customize ? "calc(100% - var(--font-size) * 2 - 11px)" : "calc(100% - var(--font-size) * 1.8 - 32px)"
})

//导入的字段
const getInData = () => {
    let inData = [];
    if (selectionInData.length === 0) {
        tableInData.forEach((e) => {
            inData.push(e.name)
        });
    } else {
        selectionInData.forEach((e) => {
            inData.push(e.name)
        });
    }
    return inData;
}
//导出的字段
const getOutData = () => {
    let outData = [];
    if (selectionOutData.length === 0) {
        tableOutData.forEach((e) => {
            outData.push(e.name)
        });
    } else {
        selectionOutData.forEach((e) => {
            outData.push(e.name)
        });
    }
    return outData;
}
//保存数据
const save = () => {
    //复制etlInfo,避免修改全局数据
    const _etlInfo = deepCopy(etlInfo)
    _etlInfo.in.column = getInData().join(";")
    _etlInfo.out.column = getOutData().join(";")
    _etlInfo.in.tableColumn = JSON.stringify(tableInData)
    _etlInfo.out.tableColumn = JSON.stringify(tableOutData)
    return _etlInfo
}

onMounted(() => {
    //加载页面时隐藏导入导出的全选按钮
    setTimeout(() => {
        changeInHeadCheckboxDisplay("none");
        changeOutHeadCheckboxDisplay("none");
    })
})

defineExpose({ save, fill, validate, fillDbInfo })

</script>
<style scoped>
:deep(.el-card__header) {
    padding: 5px;
}

:deep(.el-card__body .el-form-item) {
    height: 35px;
}

:deep(.el-card__body .sqlColumn) {
    height: 100%;
}

:deep(.table-in .el-card__body) {
    padding: v-bind(tableInPadding);
    height: v-bind(tableInHeight);
}

:deep(.table-out .el-card__body) {
    padding: 10px;
    height: calc(100% - var(--font-size)* 1.8 - 32px);
}

:deep(.table-where .el-card__body) {
    padding: 10px;
    height: calc(100% - 20px);
}

:deep(.icon) {
    font-size: 60px;
    color: rgb(143 147 0 / .5);
    animation: moveRight 2s linear infinite;
}

@keyframes moveRight {
    0% {
        left: -30px;
        transform: scale(0);
    }

    10% {
        left: -20px;
        transform: scale(.8);
    }

    20% {
        left: -10px;
        transform: scale(.9);
    }

    30% {
        left: 0;
        transform: scale(1);
    }

    40% {
        left: 10px;
        transform: scale(1.1);
    }

    50% {
        left: 20px;
        transform: scale(1.1);
    }

    60% {
        left: 30px;
        transform: scale(1.1);
    }

    70% {
        left: 40px;
        transform: scale(1);
    }

    80% {
        left: 50px;
        transform: scale(.9);
    }

    90% {
        left: 60px;
        transform: scale(.8);
    }

    100% {
        left: 70px;
        transform: scale(0);
    }
}

:deep(.el-drawer__header) {
    margin-bottom: 0 !important;
    padding: 5px 5px 0;
}

:deep(.el-form-item__error) {
    top: 21%;
    right: 10px;
    left: unset;
    pointer-events: none;
}

:deep(.sqlColumn .el-form-item__error) {
    top: 0 !important;
}

:deep(.el-checkbox__input.is-disabled .el-checkbox__inner),
:deep(.el-checkbox__input.is-disabled .el-checkbox__inner::after) {
    cursor: default;
}

:deep(.el-table--border) {
    border-radius: 5px;
}

:deep(.ace_editor) {
    margin: 0;
}

:deep(.sqlColumn .el-form-item__content) {
    margin-right: 0;
}

:deep(.el-form-item) {
    margin-bottom: 5px;
}

:deep(.el-card .el-form) {
    height: 100%;
}

:deep(.relationContainer) {
    height: 100%;
    width: 80px;
    display: flex;
    align-items: center;
    justify-content: left;
    overflow: hidden;
}

:deep(.inTable .el-table-fixed-column--left .cell),
:deep(.outTable .el-table-fixed-column--left .cell) {
    justify-content: center;
    width: 100%;
}

:deep(.el-table-header-cell .cell .el-checkbox) {
    transition: opacity .3s;
}

:deep(.el-table__empty-block) {
    height: 90% !important;
}

:deep(.el-card) {
    --el-card-border-color: rgb(0 0 0 / 10%);
}
</style>

<style>
.table-mapping-page .el-drawer__body {
    padding: 4px;
    overflow: hidden;
}
</style>